package com.utils

import com.CompressData
import com.Utils
import com.boge.utils.SystemUtils
import com.logger
import java.nio.file.Path
import java.util.concurrent.CompletableFuture
import kotlin.io.path.*

/**
 *
 *
 * 学习地址 https://pngquant.org/
 *
 */
object CompressUtils {

    private val pngquautName = "pngquant${if (SystemUtils.isWin) ".exe" else ""}"
    private val runPath: Path by lazy {
        SystemUtils.runPath.resolve(pngquautName)
    }

    @Synchronized
    fun isVerify(path: Path? = null) {
        val verifyPath = path ?: runPath
        if (!verifyPath.exists()) {
            val byte = javaClass.getResourceAsStream("/${pngquautName}")!!.readAllBytes()
            logger.debug("不存在${pngquautName}文件，执行保存 $verifyPath")
            verifyPath.writeBytes(byte)
        }
    }

    /**
     * 批量执行压缩数组中的所有图片
     */
    fun runPngQuant(compressDatas: List<CompressData>) {
        this.isVerify()
        val futures = mutableListOf<CompletableFuture<Unit>>()
        for (compressData in compressDatas) {
            val future = CompletableFuture.supplyAsync({
                compressImage(compressData)
            }, Utils.executors)
            futures.add(future)
        }
        CompletableFuture.allOf(*futures.toTypedArray()).join()
    }


    /**
     * 根据指定大小和指定精度压缩图片
     *
     * @param compressData  源图片地址
     */
    fun compressImage(compressData: CompressData) {
        if (compressData.filePath.extension == "png") {
            this.isVerify()
            val outputName = compressData.getCompressName()
            // 最终生成的文件路径
            val newPath = compressData.getCompressPath()
            // 生成过程中的临时路径
            val outTmpPath =
                Utils.tempPath.resolve("${outputName}${compressData.suffix}.${compressData.filePath.extension}")
            val runCmd = arrayOf(
                runPath.pathString,
                "-f", // --force 覆盖现有输出文件（同义词：-f）
                "-v", // 详细打印状态消息（同义词：-v）
                "--quality=${compressData.quality}",
//                "--ext=${compressData.suffix}.${compressData.filePath.extension}",
                "-o", outTmpPath.pathString,
                compressData.filePath.pathString
            )
            logger.debug("执行压缩命令： ${runCmd.joinToString(" ")}")
            val process = Runtime.getRuntime().exec(runCmd)
            val code = process.waitFor()
            if (code != 0) {
                logger.error(process.errorReader().readText())
            } else {
                logger.debug("压缩图片完成，移动到最终目录： $outTmpPath move to $newPath")
                outTmpPath.moveTo(newPath, true)
            }

            logger.debug("Compressed $compressData to $newPath")
        } else {
            if (compressData.outDir != null && compressData.keepOutFile && !compressData.filePath.startsWith(compressData.outDir)) {
                // 如果给出的输出目录不是压缩文件目录的根目录 将文件复制到输出目录防止后续找不到文件
                compressData.filePath.copyTo(compressData.getCompressPath(), true)
            }
        }
    }


}